package 设计模式.singleton;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;

//懒汉式，用的时候创建对象

public class Lazy {
    private static boolean jianghengxing=false;

    private Lazy() {
        if (jianghengxing==false){
            jianghengxing=true;
        }else {
            throw  new RuntimeException("不要试图使用反射破坏异常");
        }
        synchronized (Lazy.class){
            if (lazy!=null){
                throw  new RuntimeException("不要试图使用反射破坏异常");
            }
        }

        System.out.println(Thread.currentThread().getName() + "OK");
    }

    private volatile static Lazy lazy;

    public static Lazy getInstance() {

        //双重检索  DCL懒汉式
        if (lazy == null) {
            synchronized (Lazy.class) {
                if (lazy == null) {
                    lazy = new Lazy();//不是原子性操作

                }
            }
        }
        return lazy;//
    }

    //反射
    public static void main(String[] args) throws Exception {
//        Lazy instance = Lazy.getInstance();


        Field jianghengxing1 = Lazy.class.getDeclaredField("jianghengxing");
        jianghengxing1.setAccessible(true);

        Constructor<Lazy> declaredConstructor = Lazy.class.getDeclaredConstructor(null);//获取空参构造器
        declaredConstructor.setAccessible(true);//无视私有构造器
        Lazy instance1=declaredConstructor.newInstance();

        jianghengxing1.set(instance1,false);


        Lazy instance=declaredConstructor.newInstance();

        System.out.println(instance);
        System.out.println(instance1);
    }


          /*
                    1 分配内存空间
                    2 执行构造方法
                    3 把这个对象指向这个空间
                    期望123
                    实际可能132  A
                               B当A线程走过13之后，会直接不过第二步构造，出现指令重排！！！！！！
                     */


//    //单线程单例ok，并发
//    public static void main(String[] args) {
//        for (int i = 0; i < 10; i++) {
//            new Thread(() -> {
//                lazy.getInstance();
//            }).start();
//        }
//    }

}
